home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / asyncore.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  17.4 KB  |  653 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''Basic infrastructure for asynchronous socket service clients and servers.
  5.  
  6. There are only two ways to have a program on a single processor do "more
  7. than one thing at a time".  Multi-threaded programming is the simplest and
  8. most popular way to do it, but there is another very different technique,
  9. that lets you have nearly all the advantages of multi-threading, without
  10. actually using multiple threads. it\'s really only practical if your program
  11. is largely I/O bound. If your program is CPU bound, then pre-emptive
  12. scheduled threads are probably what you really need. Network servers are
  13. rarely CPU-bound, however.
  14.  
  15. If your operating system supports the select() system call in its I/O
  16. library (and nearly all do), then you can use it to juggle multiple
  17. communication channels at once; doing other work while your I/O is taking
  18. place in the "background."  Although this strategy can seem strange and
  19. complex, especially at first, it is in many ways easier to understand and
  20. control than multi-threaded programming. The module documented here solves
  21. many of the difficult problems for you, making the task of building
  22. sophisticated high-performance network servers and clients a snap.
  23. '''
  24. import select
  25. import socket
  26. import sys
  27. import time
  28. import os
  29. from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, errorcode
  30.  
  31. try:
  32.     socket_map
  33. except NameError:
  34.     socket_map = { }
  35.  
  36.  
  37. def _strerror(err):
  38.     res = os.strerror(err)
  39.     if res == 'Unknown error':
  40.         res = errorcode[err]
  41.     
  42.     return res
  43.  
  44.  
  45. class ExitNow(Exception):
  46.     pass
  47.  
  48.  
  49. def read(obj):
  50.     
  51.     try:
  52.         obj.handle_read_event()
  53.     except (ExitNow, KeyboardInterrupt, SystemExit):
  54.         raise 
  55.     except:
  56.         obj.handle_error()
  57.  
  58.  
  59.  
  60. def write(obj):
  61.     
  62.     try:
  63.         obj.handle_write_event()
  64.     except (ExitNow, KeyboardInterrupt, SystemExit):
  65.         raise 
  66.     except:
  67.         obj.handle_error()
  68.  
  69.  
  70.  
  71. def _exception(obj):
  72.     
  73.     try:
  74.         obj.handle_expt_event()
  75.     except (ExitNow, KeyboardInterrupt, SystemExit):
  76.         raise 
  77.     except:
  78.         obj.handle_error()
  79.  
  80.  
  81.  
  82. def readwrite(obj, flags):
  83.     
  84.     try:
  85.         if flags & (select.POLLIN | select.POLLPRI):
  86.             obj.handle_read_event()
  87.         
  88.         if flags & select.POLLOUT:
  89.             obj.handle_write_event()
  90.         
  91.         if flags & (select.POLLERR | select.POLLNVAL):
  92.             obj.handle_expt_event()
  93.         
  94.         if flags & select.POLLHUP:
  95.             obj.handle_close()
  96.     except (ExitNow, KeyboardInterrupt, SystemExit):
  97.         raise 
  98.     except:
  99.         obj.handle_error()
  100.  
  101.  
  102.  
  103. def poll(timeout = 0, map = None):
  104.     if map is None:
  105.         map = socket_map
  106.     
  107.     if map:
  108.         r = []
  109.         w = []
  110.         e = []
  111.         for fd, obj in map.items():
  112.             is_r = obj.readable()
  113.             is_w = obj.writable()
  114.             if is_r:
  115.                 r.append(fd)
  116.             
  117.             if is_w:
  118.                 w.append(fd)
  119.             
  120.             if is_r or is_w:
  121.                 e.append(fd)
  122.                 continue
  123.         
  124.         if r == r and w == w:
  125.             pass
  126.         elif w == e:
  127.             time.sleep(timeout)
  128.             return None
  129.         
  130.         try:
  131.             (r, w, e) = select.select(r, w, e, timeout)
  132.         except select.error:
  133.             err = None
  134.             if err.args[0] != EINTR:
  135.                 raise 
  136.             err.args[0] != EINTR
  137.             return None
  138.  
  139.         for fd in r:
  140.             obj = map.get(fd)
  141.             if obj is None:
  142.                 continue
  143.             
  144.             read(obj)
  145.         
  146.         for fd in w:
  147.             obj = map.get(fd)
  148.             if obj is None:
  149.                 continue
  150.             
  151.             write(obj)
  152.         
  153.         for fd in e:
  154.             obj = map.get(fd)
  155.             if obj is None:
  156.                 continue
  157.             
  158.             _exception(obj)
  159.         
  160.     
  161.  
  162.  
  163. def poll2(timeout = 0, map = None):
  164.     if map is None:
  165.         map = socket_map
  166.     
  167.     if timeout is not None:
  168.         timeout = int(timeout * 1000)
  169.     
  170.     pollster = select.poll()
  171.     if map:
  172.         for fd, obj in map.items():
  173.             flags = 0
  174.             if obj.readable():
  175.                 flags |= select.POLLIN | select.POLLPRI
  176.             
  177.             if obj.writable():
  178.                 flags |= select.POLLOUT
  179.             
  180.             if flags:
  181.                 flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL
  182.                 pollster.register(fd, flags)
  183.                 continue
  184.         
  185.         
  186.         try:
  187.             r = pollster.poll(timeout)
  188.         except select.error:
  189.             err = None
  190.             if err.args[0] != EINTR:
  191.                 raise 
  192.             err.args[0] != EINTR
  193.             r = []
  194.  
  195.         for fd, flags in r:
  196.             obj = map.get(fd)
  197.             if obj is None:
  198.                 continue
  199.             
  200.             readwrite(obj, flags)
  201.         
  202.     
  203.  
  204. poll3 = poll2
  205.  
  206. def loop(timeout = 30, use_poll = False, map = None, count = None):
  207.     if map is None:
  208.         map = socket_map
  209.     
  210.     if use_poll and hasattr(select, 'poll'):
  211.         poll_fun = poll2
  212.     else:
  213.         poll_fun = poll
  214.     if count is None:
  215.         while map:
  216.             poll_fun(timeout, map)
  217.     else:
  218.         while map and count > 0:
  219.             poll_fun(timeout, map)
  220.             count = count - 1
  221.  
  222.  
  223. class dispatcher:
  224.     debug = False
  225.     connected = False
  226.     accepting = False
  227.     closing = False
  228.     addr = None
  229.     
  230.     def __init__(self, sock = None, map = None):
  231.         if map is None:
  232.             self._map = socket_map
  233.         else:
  234.             self._map = map
  235.         self._fileno = None
  236.         if sock:
  237.             sock.setblocking(0)
  238.             self.set_socket(sock, map)
  239.             self.connected = True
  240.             
  241.             try:
  242.                 self.addr = sock.getpeername()
  243.             except socket.error:
  244.                 err = None
  245.                 if err.args[0] == ENOTCONN:
  246.                     self.connected = False
  247.                 else:
  248.                     self.del_channel(map)
  249.                     raise 
  250.                 err.args[0] == ENOTCONN
  251.             
  252.  
  253.         None<EXCEPTION MATCH>socket.error
  254.         self.socket = None
  255.  
  256.     
  257.     def __repr__(self):
  258.         status = [
  259.             self.__class__.__module__ + '.' + self.__class__.__name__]
  260.         if self.accepting and self.addr:
  261.             status.append('listening')
  262.         elif self.connected:
  263.             status.append('connected')
  264.         
  265.         if self.addr is not None:
  266.             
  267.             try:
  268.                 status.append('%s:%d' % self.addr)
  269.             except TypeError:
  270.                 status.append(repr(self.addr))
  271.             except:
  272.                 None<EXCEPTION MATCH>TypeError
  273.             
  274.  
  275.         None<EXCEPTION MATCH>TypeError
  276.         return '<%s at %#x>' % (' '.join(status), id(self))
  277.  
  278.     
  279.     def add_channel(self, map = None):
  280.         if map is None:
  281.             map = self._map
  282.         
  283.         map[self._fileno] = self
  284.  
  285.     
  286.     def del_channel(self, map = None):
  287.         fd = self._fileno
  288.         if map is None:
  289.             map = self._map
  290.         
  291.         if fd in map:
  292.             del map[fd]
  293.         
  294.         self._fileno = None
  295.  
  296.     
  297.     def create_socket(self, family, type):
  298.         self.family_and_type = (family, type)
  299.         sock = socket.socket(family, type)
  300.         sock.setblocking(0)
  301.         self.set_socket(sock)
  302.  
  303.     
  304.     def set_socket(self, sock, map = None):
  305.         self.socket = sock
  306.         self._fileno = sock.fileno()
  307.         self.add_channel(map)
  308.  
  309.     
  310.     def set_reuse_addr(self):
  311.         
  312.         try:
  313.             self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1)
  314.         except socket.error:
  315.             pass
  316.  
  317.  
  318.     
  319.     def readable(self):
  320.         return True
  321.  
  322.     
  323.     def writable(self):
  324.         return True
  325.  
  326.     
  327.     def listen(self, num):
  328.         self.accepting = True
  329.         if os.name == 'nt' and num > 5:
  330.             num = 5
  331.         
  332.         return self.socket.listen(num)
  333.  
  334.     
  335.     def bind(self, addr):
  336.         self.addr = addr
  337.         return self.socket.bind(addr)
  338.  
  339.     
  340.     def connect(self, address):
  341.         self.connected = False
  342.         err = self.socket.connect_ex(address)
  343.         if err in (EINPROGRESS, EALREADY, EWOULDBLOCK):
  344.             return None
  345.         if err in (0, EISCONN):
  346.             self.addr = address
  347.             self.handle_connect_event()
  348.         else:
  349.             raise socket.error(err, errorcode[err])
  350.         return err in (EINPROGRESS, EALREADY, EWOULDBLOCK)
  351.  
  352.     
  353.     def accept(self):
  354.         
  355.         try:
  356.             (conn, addr) = self.socket.accept()
  357.             return (conn, addr)
  358.         except socket.error:
  359.             why = None
  360.             if why.args[0] == EWOULDBLOCK:
  361.                 pass
  362.             else:
  363.                 raise 
  364.             why.args[0] == EWOULDBLOCK
  365.  
  366.  
  367.     
  368.     def send(self, data):
  369.         
  370.         try:
  371.             result = self.socket.send(data)
  372.             return result
  373.         except socket.error:
  374.             why = None
  375.             if why.args[0] == EWOULDBLOCK:
  376.                 return 0
  377.             if why.args[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED):
  378.                 self.handle_close()
  379.                 return 0
  380.             raise 
  381.         except:
  382.             why.args[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED)
  383.  
  384.  
  385.     
  386.     def recv(self, buffer_size):
  387.         
  388.         try:
  389.             data = self.socket.recv(buffer_size)
  390.             if not data:
  391.                 self.handle_close()
  392.                 return ''
  393.             return data
  394.         except socket.error:
  395.             why = None
  396.             if why.args[0] in [
  397.                 ECONNRESET,
  398.                 ENOTCONN,
  399.                 ESHUTDOWN,
  400.                 ECONNABORTED]:
  401.                 self.handle_close()
  402.                 return ''
  403.             raise 
  404.         except:
  405.             why.args[0] in [
  406.                 ECONNRESET,
  407.                 ENOTCONN,
  408.                 ESHUTDOWN,
  409.                 ECONNABORTED]
  410.  
  411.  
  412.     
  413.     def close(self):
  414.         self.connected = False
  415.         self.accepting = False
  416.         self.del_channel()
  417.         
  418.         try:
  419.             self.socket.close()
  420.         except socket.error:
  421.             why = None
  422.             if why.args[0] not in (ENOTCONN, EBADF):
  423.                 raise 
  424.             why.args[0] not in (ENOTCONN, EBADF)
  425.  
  426.  
  427.     
  428.     def __getattr__(self, attr):
  429.         return getattr(self.socket, attr)
  430.  
  431.     
  432.     def log(self, message):
  433.         sys.stderr.write('log: %s\n' % str(message))
  434.  
  435.     
  436.     def log_info(self, message, type = 'info'):
  437.         if __debug__ or type != 'info':
  438.             print '%s: %s' % (type, message)
  439.         
  440.  
  441.     
  442.     def handle_read_event(self):
  443.         if self.accepting:
  444.             self.handle_accept()
  445.         elif not self.connected:
  446.             self.handle_connect_event()
  447.             self.handle_read()
  448.         else:
  449.             self.handle_read()
  450.  
  451.     
  452.     def handle_connect_event(self):
  453.         self.connected = True
  454.         self.handle_connect()
  455.  
  456.     
  457.     def handle_write_event(self):
  458.         if self.accepting:
  459.             return None
  460.         if not self.connected:
  461.             err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
  462.             if err != 0:
  463.                 raise socket.error(err, _strerror(err))
  464.             err != 0
  465.             self.handle_connect_event()
  466.         
  467.         self.handle_write()
  468.  
  469.     
  470.     def handle_expt_event(self):
  471.         x = True
  472.         
  473.         try:
  474.             y1 = self.__class__.handle_expt.im_func
  475.             y2 = dispatcher.handle_expt.im_func
  476.             x = y1 is y2
  477.         except AttributeError:
  478.             pass
  479.  
  480.         if x:
  481.             err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
  482.             msg = _strerror(err)
  483.             raise socket.error(err, msg)
  484.         x
  485.         self.handle_expt()
  486.  
  487.     
  488.     def handle_error(self):
  489.         (nil, t, v, tbinfo) = compact_traceback()
  490.         
  491.         try:
  492.             self_repr = repr(self)
  493.         except:
  494.             self_repr = '<__repr__(self) failed for object at %0x>' % id(self)
  495.  
  496.         self.log_info('uncaptured python exception, closing channel %s (%s:%s %s)' % (self_repr, t, v, tbinfo), 'error')
  497.         self.handle_close()
  498.  
  499.     
  500.     def handle_expt(self):
  501.         self.log_info('unhandled exception', 'warning')
  502.  
  503.     
  504.     def handle_read(self):
  505.         self.log_info('unhandled read event', 'warning')
  506.  
  507.     
  508.     def handle_write(self):
  509.         self.log_info('unhandled write event', 'warning')
  510.  
  511.     
  512.     def handle_connect(self):
  513.         self.log_info('unhandled connect event', 'warning')
  514.  
  515.     
  516.     def handle_accept(self):
  517.         self.log_info('unhandled accept event', 'warning')
  518.  
  519.     
  520.     def handle_close(self):
  521.         self.log_info('unhandled close event', 'warning')
  522.         self.close()
  523.  
  524.  
  525.  
  526. class dispatcher_with_send(dispatcher):
  527.     
  528.     def __init__(self, sock = None, map = None):
  529.         dispatcher.__init__(self, sock, map)
  530.         self.out_buffer = ''
  531.  
  532.     
  533.     def initiate_send(self):
  534.         num_sent = 0
  535.         num_sent = dispatcher.send(self, self.out_buffer[:512])
  536.         self.out_buffer = self.out_buffer[num_sent:]
  537.  
  538.     
  539.     def handle_write(self):
  540.         self.initiate_send()
  541.  
  542.     
  543.     def writable(self):
  544.         if not not (self.connected):
  545.             pass
  546.         return len(self.out_buffer)
  547.  
  548.     
  549.     def send(self, data):
  550.         if self.debug:
  551.             self.log_info('sending %s' % repr(data))
  552.         
  553.         self.out_buffer = self.out_buffer + data
  554.         self.initiate_send()
  555.  
  556.  
  557.  
  558. def compact_traceback():
  559.     (t, v, tb) = sys.exc_info()
  560.     tbinfo = []
  561.     if not tb:
  562.         raise AssertionError('traceback does not exist')
  563.     tb
  564.     while tb:
  565.         tbinfo.append((tb.tb_frame.f_code.co_filename, tb.tb_frame.f_code.co_name, str(tb.tb_lineno)))
  566.         tb = tb.tb_next
  567.     del tb
  568.     (file, function, line) = tbinfo[-1]
  569.     info = []([ '[%s|%s|%s]' % x for x in tbinfo ])
  570.     return ((file, function, line), t, v, info)
  571.  
  572.  
  573. def close_all(map = None, ignore_all = False):
  574.     if map is None:
  575.         map = socket_map
  576.     
  577.     for x in map.values():
  578.         
  579.         try:
  580.             x.close()
  581.         continue
  582.         except OSError:
  583.             x = None
  584.             if x.args[0] == EBADF:
  585.                 pass
  586.             elif not ignore_all:
  587.                 raise 
  588.             
  589.             x.args[0] == EBADF
  590.             except (ExitNow, KeyboardInterrupt, SystemExit):
  591.                 raise 
  592.                 continue
  593.                 if not ignore_all:
  594.                     raise 
  595.                 ignore_all
  596.                 continue
  597.             
  598.         return None
  599.  
  600.  
  601. if os.name == 'posix':
  602.     import fcntl
  603.     
  604.     class file_wrapper:
  605.         
  606.         def __init__(self, fd):
  607.             self.fd = os.dup(fd)
  608.  
  609.         
  610.         def recv(self, *args):
  611.             return os.read(self.fd, *args)
  612.  
  613.         
  614.         def send(self, *args):
  615.             return os.write(self.fd, *args)
  616.  
  617.         read = recv
  618.         write = send
  619.         
  620.         def close(self):
  621.             os.close(self.fd)
  622.  
  623.         
  624.         def fileno(self):
  625.             return self.fd
  626.  
  627.  
  628.     
  629.     class file_dispatcher(dispatcher):
  630.         
  631.         def __init__(self, fd, map = None):
  632.             dispatcher.__init__(self, None, map)
  633.             self.connected = True
  634.             
  635.             try:
  636.                 fd = fd.fileno()
  637.             except AttributeError:
  638.                 pass
  639.  
  640.             self.set_file(fd)
  641.             flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
  642.             flags = flags | os.O_NONBLOCK
  643.             fcntl.fcntl(fd, fcntl.F_SETFL, flags)
  644.  
  645.         
  646.         def set_file(self, fd):
  647.             self.socket = file_wrapper(fd)
  648.             self._fileno = self.socket.fileno()
  649.             self.add_channel()
  650.  
  651.  
  652.  
  653.